<script>
export default {
  name: 'DesignCanvas',
}
</script>
<template>
  <div class="canvas" id="canvasDesign">
    <div class="preview-content" ref="canvasRef" :style="bodyStyle">
      <div
        class="preview-content-list"
        :style="item.styleOptions"
        v-for="(item, index) in layoutList"
        :key="index"
      >
        <template v-if="item.type === 'Image'">
          <DesignImage :formData="item"></DesignImage>
        </template>
        <template v-if="item.type === 'Video'">
          <DesignVideo :formData="item"></DesignVideo>
        </template>
        <template v-if="item.type === 'Text'">
          <DesignText :formData="item"></DesignText>
        </template>
        <template v-if="item.type === 'Time'">
          <DesignTime :formData="item"></DesignTime>
        </template>
      </div>
    </div>
  </div>
</template>
<script setup>
import useDesignStore from '@/store/modules/baseDesign'
import DesignImage from './components/DesignImage.vue'
import DesignVideo from './components/DesignVideo.vue'
import DesignText from './components/DesignText.vue'
import DesignTime from './components/DesignTime.vue'
import { convertImageToBase64, convertVideoToBase64 } from '@/utils/index'
import html2canvas from 'html2canvas'
let bodyStyle = ref([])
let canvasRef = ref()

let layoutList = ref([])
function init() {
  let list = useDesignStore().getLayoutList
  list.map((item) => {
    item.styleOptions = {
      width: `${item.w}px`,
      height: `${item.h}px`,
      top: `${item.y}px`,
      left: `${item.x}px`,
      zIndex: item.z,
      backgroundColor: `${item.style.background}`,
    }
  })
  layoutList.value = list
  return Promise.resolve()
}

watch(
  () => canvasRef.value,
  (newVal) => {
    if (newVal) {
      computedScale()
    }
  },
)
window.onresize = () => {
  if (canvasRef.value) {
    computedScale()
  }
}
function computedScale() {
  let body = useDesignStore().getBody
  let rect = canvasRef.value.getBoundingClientRect()
  let { height, width } = rect
  let scaleHeight = height / body.resolutionRatio[1]
  let scaleWidth = width / body.resolutionRatio[0]
  let scale = Math.min(scaleHeight, scaleWidth)
  let scaleZoom = Math.min(scale, 1)
  bodyStyle.value = {
    zoom: scaleZoom,
  }
}
async function renderImage() {
  return new Promise((resolve, reject) => {
    let previewDom = null
    init().then(() => {
      previewDom = document.querySelector('#canvasDesign')
      let domList = previewDom.querySelectorAll('.image')
      let promiseAll = []
      for (let i = 0; i < domList.length; i++) {
        if (domList[i].localName == 'video') {
          let src = domList[i].querySelector('source').src
          promiseAll.push(convertVideoToBase64(src, 'video'))
        } else {
          promiseAll.push(convertImageToBase64(domList[i].src, 'image'))
        }
      }
      Promise.allSettled(promiseAll)
        .then((res) => {
          res.forEach((item, index) => {
            if (item.status == 'fulfilled') {
              if (item.value.type == 'video') {
                domList[index].parentNode.querySelector('.video-image').src =
                  item.value.dataURL
              } else {
                domList[index].src = item.value.dataURL
              }
            }
          })
        })
        .then(() => {
          html2canvas(previewDom)
            .then((canvas) => {
              const base64Image = canvas.toDataURL('image/png')
              resolve(base64Image)
            })
            .catch((err) => {
              console.error('html2canvas', err)
            })
        })
        .catch((err) => {
          console.error(err)
          reject()
        })
    })
  })
}
defineExpose({
  renderImage,
})
</script>
<style scoped>
.canvas {
  height: 100vh;
  overflow: hidden;
  width: 100vw;
  position: absolute;
  z-index: -100;
  /* display: none; */
}
.image {
  width: 100%;
  height: 100%;
}
.preview-content {
  position: relative;
  height: 100%;
  height: 100%;
}
.preview-content-list {
  position: absolute;
}
:deep(.el-dialog__body) {
  width: 100%;
  height: 100%;
}
</style>
